package com.nuoniu.sibanyun.service.crm.call.callbackLine.impl;

import com.alibaba.fastjson.JSON;
import com.nuoniu.sibanyun.common.constant.CrmCallConstant;
import com.nuoniu.sibanyun.common.exception.NuoNiuException;
import com.nuoniu.sibanyun.common.lang.StringUtils;
import com.nuoniu.sibanyun.entity.crm.call.CrmCallAgent;
import com.nuoniu.sibanyun.entity.crm.call.CrmCallAppInfo;
import com.nuoniu.sibanyun.entity.crm.call.CrmCallTaskRecord;
import com.nuoniu.sibanyun.entity.crm.call.rongying.*;
import com.nuoniu.sibanyun.entity.crm.call.rongying.dto.BillDto;
import com.nuoniu.sibanyun.entity.crm.call.rongying.dto.BillListDto;
import com.nuoniu.sibanyun.entity.crm.call.rongying.dto.CallDetailDto;
import com.nuoniu.sibanyun.entity.crm.call.rongying.dto.CallRecordDto;
import com.nuoniu.sibanyun.entity.crm.call.rongying.enumEntity.FailReason;
import com.nuoniu.sibanyun.entity.webSocket.WebSocketResult;
import com.nuoniu.sibanyun.service.crm.call.ICrmCallAgentService;
import com.nuoniu.sibanyun.service.crm.call.ICrmCallAppInfoService;
import com.nuoniu.sibanyun.service.crm.call.ICrmCallTaskRecordService;
import com.nuoniu.sibanyun.service.crm.call.callbackLine.ICallbackLineService;
import com.nuoniu.sibanyun.service.msg.WebSocketService;
import com.nuoniu.sibanyun.service.redis.RedisService;
import com.nuoniu.sibanyun.userThread.UserInfo;
import com.nuoniu.sibanyun.userThread.UserThreadLocal;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * @ClassName CallbackLineServiceImpl
 * @Description TODO
 * @Author 白强
 * @Date 2022/6/16 10:59
 * @Version 1.0
 **/
@Log4j2
@Service
public class CallbackLineServiceImpl implements ICallbackLineService {

    @Autowired
    private ICrmCallAgentService callAgentService;
    @Autowired
    private ICrmCallAppInfoService crmCallAppInfoService;
    @Autowired
    private ICrmCallTaskRecordService crmCallTaskRecordService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private WebSocketService socketService;


    @Override
    public RongYingCallResult call(CallMode callMode) {
        RongYingCallResult rongYingCallResult = new RongYingCallResult();
        UserInfo userInfo = UserThreadLocal.get();

        Integer callAppId = userInfo.getCallAppId();
        if(null == callAppId) {
            throw new NuoNiuException("APPID：外呼配置错误，请联系管理员");
        }
        CrmCallAgent myCrmCallAgent = callAgentService.getMyCrmCallAgent();
        if(null == myCrmCallAgent) {
            throw new NuoNiuException("你没有绑定坐席");
        }
        //主叫号码
        String Caller = myCrmCallAgent.getPhone();
        if(StringUtils.isBlank(Caller)) {
            throw new NuoNiuException("坐席没有绑定电话号码");
        }
        CrmCallAppInfo appInfo = crmCallAppInfoService.getById(callAppId);
        String accountSid = appInfo.getAccountSid();  //授权令牌
        String appId = appInfo.getAppId();  //应用Id
        String appToken = appInfo.getAppToken(); //应用Token
        String Callee = callMode.getCallee();  //被叫号码

        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String TimeStr=sdf.format(d);
        String urlString="https://wdapi.yuntongxin.vip/20200305/rest/click/call/event/v1?sig="; //坐席外呼请求链接地址
        String  sig = ToolUtils.GetMd5( accountSid + ":" + appId  +":"+ TimeStr);
        String auth= ToolUtils.GetBase64(appId +":" + appToken +":"+ TimeStr);
        Map<String, String> infos = new HashMap<>();
        infos.put("Appid", appId);
        infos.put("AccountSid", accountSid);
        infos.put("Caller", Caller);
        infos.put("Callee",Callee);
        infos.put("IsDisplayCalleeNbr","false");
        String reString = ToolUtils.sendPost(urlString+sig,infos,auth);
        log.info("融营 拨打，返回结果：{}",reString);
        if(StringUtils.isNotBlank(reString)){
            RongYingCallResult callResult = JSON.parseObject(reString, RongYingCallResult.class);
            Integer flag = callResult.getFlag();
            if(flag.equals(200)){
                /** 新增通话记录 */
//                boolean isSetAppInfoOk = redisService.set(CrmCallConstant.CALL_APP + callAppId, appInfo, 3600);
//                if(!isSetAppInfoOk){
//                    log.info("callAppId:{},外呼应用存放Redis失败",callAppId);
//                }
//                boolean set1 = redisService.set(CrmCallConstant.RY_SESSION_ID_CALL_APP + callResult.getSessionId(), callAppId, 36000);
                crmCallTaskRecordService.addFromCallMode(userInfo,myCrmCallAgent,callMode,callResult);
            }
            return callResult;
        }else {
            rongYingCallResult.setFlag(500);
            rongYingCallResult.setMsg("请求失败");
        }
        return rongYingCallResult;
    }

    @Override
    public RongYingCallResult hangUp(String SessionId) {
        RongYingCallResult rongYingCallResult = new RongYingCallResult();
        UserInfo userInfo = UserThreadLocal.get();
        Integer callAppId = userInfo.getCallAppId();
        if(null == callAppId) {
            throw new NuoNiuException("APPID：外呼配置错误，请联系管理员");
        }
        CrmCallAppInfo appInfo = crmCallAppInfoService.getById(callAppId);
        String accountSid = appInfo.getAccountSid();  //授权令牌
        String appId = appInfo.getAppId();  //应用Id
        String appToken = appInfo.getAppToken(); //应用Token
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String TimeStr=sdf.format(d);
        String urlString="https://wdapi.yuntongxin.vip/20200301/rest/click/call/stop/event/v1?sig="; // 坐席 终止呼叫 请求链接地址
        String  sig = ToolUtils.GetMd5( accountSid + ":" + appId  +":"+ TimeStr);
        String auth=  ToolUtils.GetBase64(appId +":" + appToken +":"+ TimeStr);
        Map<String, String> infos = new HashMap<>();
        infos.put("SessionId", SessionId);

        String reString = ToolUtils.sendPost(urlString+sig,infos,auth);
        log.info("融营 挂机，返回结果：{}",reString);
        if(StringUtils.isNotBlank(reString)) {
            rongYingCallResult = JSON.parseObject(reString, RongYingCallResult.class);
        }else{
            rongYingCallResult.setFlag(500);
            rongYingCallResult.setMsg("请求失败");
        }
        return rongYingCallResult;
    }

    @Override
    public void getRecord(String sessionId) {
        long startTime = System.currentTimeMillis();
        CallRecordDto callRecordDto = new CallRecordDto();
        CallDetailDto callDetail = new CallDetailDto();
        callRecordDto.setCallDetail(callDetail);
        callDetail.setSessionId(sessionId);
        Object callAppId = redisService.get(CrmCallConstant.RY_SESSION_ID_CALL_APP + sessionId);
        if(null == callAppId) {
            log.info("1.sessionId:{},Redis查询不到应用callAppId",sessionId);
            return;
        }
        Object appInfoObj = redisService.get(CrmCallConstant.CALL_APP + callAppId);
        if(null == appInfoObj){
            log.info("2.callAppId:{},Redis查询不到应用",callAppId);
            return;
        }
        CrmCallAppInfo appInfo = (CrmCallAppInfo)appInfoObj;
        String accountSid = appInfo.getAccountSid();  //授权令牌
        String appId = appInfo.getAppId();  //应用Id
        String appToken = appInfo.getAppToken(); //应用Token
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String TimeStr=sdf.format(d);
        String urlString="https://wdapi.yuntongxin.vip/20200306/rest/click/call/record/v1?sig="; //
        String sig = ToolUtils.GetMd5( accountSid + ":" + appId  +":"+ TimeStr);
        String auth = ToolUtils.GetBase64(appId +":" + appToken +":"+ TimeStr);
        String param = JSON.toJSONString(callRecordDto);
        log.info("获取话单,参数：{}",param);
        String reString = ToolUtils.sendPostSimple(urlString + sig , param , auth);
        if(StringUtils.isNotBlank(reString)){
            RongYingCallBack rongYingCallBack = JSON.parseObject(reString, RongYingCallBack.class);
//            this.recordCallBack(rongYingCallBack);
            if(rongYingCallBack.getTotal() > 0){
                redisService.del(CrmCallConstant.RY_SESSION_ID_CALL_APP + sessionId);
            }
        }
        long endTime = System.currentTimeMillis();
        log.info("获取话单耗时：{} 毫秒",endTime - startTime);
    }

    @Override
    public void batchRecordList() {
        DateTimeFormatter timeDtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        BillDto billDto = new BillDto();
        BillListDto billList = new BillListDto();
        billDto.setBillList(billList);
        String startTime = LocalDateTime.now().minusMinutes(10L).format(timeDtf);
        billList.setStartTime(startTime);
        billList.setIsPushFail(0);
        List<CrmCallAppInfo> list = crmCallAppInfoService.list();

    }

    @Override
    public void batchRecordList(BillDto billDto,CrmCallAppInfo appInfo) {
        String accountSid = appInfo.getAccountSid();  //授权令牌
        String appId = appInfo.getAppId();  //应用Id
        String appToken = appInfo.getAppToken(); //应用Token
        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        String TimeStr=sdf.format(d);
        String urlString="https://wdapi.yuntongxin.vip/rest/click/recordlist/v2?sig="; //
        String sig = ToolUtils.GetMd5( accountSid + ":" + appId  +":"+ TimeStr);
        String auth = ToolUtils.GetBase64(appId +":" + appToken +":"+ TimeStr);
        String param = JSON.toJSONString(billDto);
        String reString = ToolUtils.sendPostSimple(urlString + sig , param , auth);
        if(StringUtils.isNotBlank(reString)){
            RongYingCallBack rongYingCallBack = JSON.parseObject(reString, RongYingCallBack.class);


        }


    }

    @Override
    @Async
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public RongYingResult recordCallBack(RongYingCallBack rongYingCallBack) {

        Integer flag = rongYingCallBack.getFlag();
        if(null == flag || !flag.equals(1)){
            return RongYingResult.error(500,"失败");
        }
        List<RongYingCallBackRecord> data = rongYingCallBack.getData();
        List<CrmCallTaskRecord> downAudioRecordList = new ArrayList<>();
        int size = data.size();
        for (int i = 0; i < size; i++) {

            RongYingCallBackRecord rongYingCallBackRecord = data.get(i);
            String sessionId = rongYingCallBackRecord.getSessionId();
            /** 1.获取 未处理的 通话记录 ***/
            CrmCallTaskRecord crmCallTaskRecord = crmCallTaskRecordService.getRecordByTalkId(sessionId);
            if(null == crmCallTaskRecord){
                continue;
            }
            Integer billsec = rongYingCallBackRecord.getBillsec();
            String fwdUnaswRsn = rongYingCallBackRecord.getFwdUnaswRsn();
            // 转换
            String ulFailReason = rongYingCallBackRecord.getUlFailReason();
            if(StringUtils.isNotBlank(ulFailReason)){
                crmCallTaskRecord.setCallResultState(ulFailReason);
                crmCallTaskRecord.setCallResultStateRemark(FailReason.getValueByKey(ulFailReason));
            }
            // 时间转换
            String callOutStartTime = rongYingCallBackRecord.getCallOutStartTime();
            String callOutAlertingTime = rongYingCallBackRecord.getCallOutAlertingTime();
            String callOutAnswerTime = rongYingCallBackRecord.getCallOutAnswerTime();
            String callEndTime = rongYingCallBackRecord.getCallEndTime();
            DateTimeFormatter timeDtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            if(StringUtils.isNotBlank(callOutStartTime)){
                rongYingCallBackRecord.setStartTime(LocalDateTime.parse(callOutStartTime, timeDtf).plusHours(8).format(timeDtf));
            }
            if(StringUtils.isNotBlank(callOutAlertingTime)){
                rongYingCallBackRecord.setAlertingTime(LocalDateTime.parse(callOutAlertingTime, timeDtf).plusHours(8).format(timeDtf));
            }
            if(StringUtils.isNotBlank(callOutAnswerTime) && (null != billsec && billsec > 0)){
                rongYingCallBackRecord.setAnswerTime(LocalDateTime.parse(callOutAnswerTime, timeDtf).plusHours(8).format(timeDtf));
            }
            if(StringUtils.isNotBlank(callEndTime)){
                rongYingCallBackRecord.setEndTime(LocalDateTime.parse(callEndTime, timeDtf).plusHours(8).format(timeDtf));
            }
            crmCallTaskRecord.setCallBackJson(JSON.toJSONString(rongYingCallBackRecord));



            if(null != billsec){
                crmCallTaskRecord.setTalkTime(billsec);
                if(billsec > 0){
                    crmCallTaskRecord.setCallResult(1);
                }else {
                    crmCallTaskRecord.setCallResult(0);
                }
            }else {
                crmCallTaskRecord.setTalkTime(0);
                crmCallTaskRecord.setCallResult(0);
            }
            /** 当前使用分钟数*/
            Integer usedMinutes =  crmCallTaskRecord.getTalkTime() / 60 + (crmCallTaskRecord.getTalkTime() % 60 > 0 ? 1: 0);
            crmCallTaskRecord.setUsedMinutes(usedMinutes);
            /** 通话语音 远端下载地址*/
            String recordFileDownloadUrl = rongYingCallBackRecord.getRecordFileDownloadUrl();
            if(StringUtils.isNotBlank(recordFileDownloadUrl)){
                crmCallTaskRecord.setCallAudioRemotePath(recordFileDownloadUrl);
                downAudioRecordList.add(crmCallTaskRecord);
            }
            /** 更新通话记录 */
            crmCallTaskRecordService.updateById(crmCallTaskRecord);
            Long crmCallTaskDetailId = crmCallTaskRecord.getCrmCallTaskDetailId();
            if(null != crmCallTaskDetailId){
                crmCallTaskRecordService.updateTaskAndDetailStatistics(crmCallTaskRecord, crmCallTaskDetailId,crmCallTaskRecord.getCrmCallTaskId());
            }
            /** 接通后，计费*/
            if(usedMinutes> 0){
                crmCallTaskRecordService.chargingAndBill(crmCallTaskRecord);
            }
        }
        /** 批量 下载音频(24小时 去下载) */
//        crmCallTaskRecordService.downAudioRemote(downAudioRecordList);
        return RongYingResult.ok("成功");
    }

    @Override
    public void listenerState(RongYingCallState rongYingCallState) {
        log.info("融营 拨打状态监听 接收消息:{}",JSON.toJSONString(rongYingCallState));
        String caller = rongYingCallState.getCaller();

        if(StringUtils.isBlank(caller)) {
            return;
        }
        caller = caller.replace("+86","");
        CrmCallAgent crmCallAgent = callAgentService.getByPhone(caller);
        WebSocketResult<RongYingCallState> webSocketResult = new WebSocketResult<>();
        if(null != crmCallAgent){
            webSocketResult.setBusinessType("RYCallState");
            webSocketResult.setData(rongYingCallState);
            if(null !=crmCallAgent.getBindingUserId()){
                socketService.sendOneMessage(crmCallAgent.getBindingUserId().toString(),JSON.toJSONString(webSocketResult));
            }
        }
//        String sessionId = rongYingCallState.getSessionId();
//        String eventType = rongYingCallState.getEventType();
//        if("disconnect".equals(eventType)){
//            this.getRecord(sessionId);
//        }
    }




}
